package edu.tsinghua.oxy.leader.service.impl;

import edu.tsinghua.oxy.common.constant.CodeConstants;
import edu.tsinghua.oxy.common.constant.SpiderConstants;
import edu.tsinghua.oxy.common.entity.Result;
import edu.tsinghua.oxy.common.repository.IBaseRedisRepository;
import edu.tsinghua.oxy.leader.service.IJobService;
import edu.tsinghua.oxy.common.utils.UrlUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.net.MalformedURLException;
import java.util.Set;

/**
 * 下发Job的service
 *
 * @author sean
 * @date 2021 - 07 - 29 下午1:52
 */
@Slf4j
@Service
public class JobServiceImpl implements IJobService {

    @Resource
    IBaseRedisRepository redisRepository;

    @Resource
    UrlUtils urlUtils;

    /**
     * 初始化任务（队列）
     */
    @Override
    public void initJob() {
        Set<String> domains = redisRepository.smembers(SpiderConstants.SPIDER_WEBSITE_DOMAINS_KEY);
        // 删除域名
        redisRepository.del(SpiderConstants.SPIDER_WEBSITE_DOMAINS_KEY);
        String higherUrlKey;
        String lowerUrlKey;
        String pageKey;
        for(String domain : domains) {
            higherUrlKey = domain + SpiderConstants.SPIDER_DOMAIN_HIGHER_SUFFIX;
            lowerUrlKey = domain + SpiderConstants.SPIDER_DOMAIN_LOWER_SUFFIX;
            pageKey = domain + SpiderConstants.SPIDER_DOMAIN_PAGE_SUFFIX;
            // 删除高低优先级队列
            redisRepository.del(higherUrlKey,lowerUrlKey,pageKey);
        }
    }

    /**
     * 将seed列表加入高优先级队列
     * 目前此接口无用，如果需要更新数据的话，后续更新此接口
     */
    @Override
    public void seedsJob() {
        /**
         * 1.从指定url种子仓库获取种子url
         * 2.将种子url添加进高优先级列表
         */
        // spider.seed.urls Redis数据类型为set，防止重复添加种子url
        Set<String> seedUrls = redisRepository.smembers(SpiderConstants.SPIDER_SEED_URLS_KEY);
        for(String seedUrl : seedUrls) {
            // 种子url的顶级域名
            Result result = seedJob(seedUrl);
            if (!CodeConstants.SUCCESS.equals(result.getCode())){
                continue;
            }
            String domain = result.getMsg();
            redisRepository.sadd(domain + SpiderConstants.SPIDER_DOMAIN_HIGHER_SUFFIX, seedUrl);
            log.info("获取种子:{}", seedUrl);
        }
    }

    /**
     * 将seed加入高优先级队列
     * @param seedUrl
     * @return Result
     */
    @Override
    public Result<Object> seedJob(String seedUrl) {
        /**
         * 将种子url添加进高优先级列表
         */
        String domain;
        try {
            domain = urlUtils.getDomainName(seedUrl);
        } catch (MalformedURLException e) {
            log.error("获取顶级域名失败，Url：{}", seedUrl, e);
            return Result.back(CodeConstants.ERROR,"获取顶级域名失败");
        }
        // 写入种子列表
        redisRepository.sadd(SpiderConstants.SPIDER_SEED_URLS_KEY, seedUrl);
        // 写入高优先级队列
        redisRepository.sadd(domain + SpiderConstants.SPIDER_DOMAIN_HIGHER_SUFFIX, seedUrl);
        // 写入域名列表
        redisRepository.sadd(SpiderConstants.SPIDER_WEBSITE_DOMAINS_KEY, domain);
        log.info("获取种子:{}", seedUrl);
        return Result.success(domain);
    }
}
